GtkWindow: make popover stacking explicit
authorCarlos Garnacho <carlosg@gnome.org>
Thu, 22 Oct 2015 16:09:23 +0000 (18:09 +0200)
committerMatthias Clasen <mclasen@redhat.com>
Tue, 3 Nov 2015 12:14:36 +0000 (07:14 -0500)
The list of popovers will specify the stacking order, a
_gtk_window_raise_popover() private call has been added so popover
widgets can request being on top.

Also, the stacking on popovers is ensured on gtk_window_size_allocate(),
after the size/stacking changes on the child widget have finished, this
will ensure popovers are kept on top of window contents.

https://bugzilla.gnome.org/show_bug.cgi?id=756670

gtk/gtkwindow.c
gtk/gtkwindowprivate.h

index 61888d47ed31100b77db6547a137924dd5aeefae..d37052a30c89b467e5bd2e21debd87fd0a093747 100644 (file)
@@ -6146,7 +6146,7 @@ popover_map (GtkWidget        *widget,
 {
   if (popover->window && gtk_widget_get_visible (popover->widget))
     {
-      gdk_window_show (popover->window);
+      gdk_window_show_unraised (popover->window);
       gtk_widget_map (popover->widget);
       popover->unmap_id = g_signal_connect (popover->widget, "unmap",
                                             G_CALLBACK (popover_unmap), popover);
@@ -7503,7 +7503,7 @@ popover_size_allocate (GtkWidget        *widget,
       gtk_widget_is_visible (widget))
     {
       if (!gdk_window_is_visible (popover->window))
-        gdk_window_show (popover->window);
+        gdk_window_show_unraised (popover->window);
     }
   else if (gdk_window_is_visible (popover->window))
     gdk_window_hide (popover->window);
@@ -7616,6 +7616,22 @@ _gtk_window_set_allocation (GtkWindow           *window,
 
 }
 
+static void
+gtk_window_restack_popovers (GtkWindow *window)
+{
+  GtkWindowPrivate *priv = window->priv;
+  GList *link = priv->popovers;
+
+  while (link)
+    {
+      GtkWindowPopover *popover = link->data;
+      link = link->next;
+
+      if (popover->window && gdk_window_is_visible (popover->window))
+        gdk_window_raise (popover->window);
+    }
+}
+
 static void
 gtk_window_size_allocate (GtkWidget     *widget,
                           GtkAllocation *allocation)
@@ -7629,6 +7645,8 @@ gtk_window_size_allocate (GtkWidget     *widget,
   child = gtk_bin_get_child (GTK_BIN (window));
   if (child && gtk_widget_get_visible (child))
     gtk_widget_size_allocate (child, &child_allocation);
+
+  gtk_window_restack_popovers (window);
 }
 
 static gint
@@ -12108,6 +12126,27 @@ _gtk_window_is_popover_widget (GtkWindow *window,
   return _gtk_window_has_popover (window, possible_popover) != NULL;
 }
 
+void
+_gtk_window_raise_popover (GtkWindow *window,
+                           GtkWidget *widget)
+{
+  GtkWindowPrivate *priv = window->priv;
+  GList *link;
+
+  for (link = priv->popovers; link; link = link->next)
+    {
+      GtkWindowPopover *popover = link->data;
+
+      if (popover->widget != widget)
+        continue;
+
+      priv->popovers = g_list_remove_link (priv->popovers, link);
+      priv->popovers = g_list_append (priv->popovers, link->data);
+      g_list_free (link);
+      break;
+    }
+}
+
 static GtkWidget *inspector_window = NULL;
 
 static void set_warn_again (gboolean warn);
index 986ca46a79b5b9984a9ed074e3a72ee67722ca94..80253bf55cfe3cc4bb95a06b9e484623ff31fee6 100644 (file)
@@ -117,6 +117,8 @@ void    _gtk_window_get_popover_position (GtkWindow                   *window,
                                           GtkWidget                   *popover,
                                           GtkPositionType             *pos,
                                           cairo_rectangle_int_t       *rect);
+void    _gtk_window_raise_popover        (GtkWindow                   *window,
+                                          GtkWidget                   *popover);
 
 GtkWidget * _gtk_window_get_popover_parent (GtkWindow *window,
                                             GtkWidget *popover);